package com.acxy.ants.core.proxy;

import net.sf.cglib.proxy.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * CGLIB动态代理
 *
 * @author MrShun
 * @version 1.0
 * @Date 2017-05-02
 */
public class CGLibProxy implements InvocationHandler {

    private static final Logger logger = LoggerFactory.getLogger(CGLibProxy.class);

    private Object target;

    public CGLibProxy(Object target) {
        this.target = target;
    }

    /**
     * 创建代理对象
     *
     * @return
     */
    public static <T> T createProxy(Object target) {
        //创建一个织入器
        Enhancer enhancer = new Enhancer();
        // 2.设置被代理类字节码，CGLIB根据字节码生成被代理类的子类
        enhancer.setSuperclass(target.getClass());
        // 3.//设置回调函数，即一个方法拦截
        enhancer.setCallback(new CGLibProxy(target));
        // 4.创建代理:
        return (T) enhancer.create();
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        method.setAccessible(true); //取消方法类型检查提高性能
        CacheInvcation cacheInvcation = new CacheInvcation(target, method, args);
        Object result = cacheInvcation.handler();
        if(result != null) return result;
        TransactionInvocation tx = new TransactionInvocation(target, method);
        try {
            result = AopInvocation.handler(target, method, args);
            tx.commit();
            cacheInvcation.cacheResult(result);
        } catch (Exception e) {
            tx.rollback();
            throw e.getCause();
        }
        return result;
    }
}
